<?php
/*
* phpCan - http://idc.anavallasuiza.com/
*
* phpCan is released under the GNU Affero GPL version 3
*
* More information at license.txt
*/

namespace data\databases;

defined('ANS') or die();

class Mysql implements iDatabase {
	private $res;
	private $Debug;
	private $conn;
	private $connection = '';
	private $settings = array();
	private $query_register = array();


	/**
	 * public function __construct ([string $connection])
	 *
	 * return none
	 */
	public function __construct ($connection = '') {
		global $Debug;

		$this->Debug = $Debug;
		$this->setConnection($connection);
	}


	/**
	 * public function setConnection ([string $connection])
	 *
	 * Set a connection name to followings operations and connect to database
	 *
	 * return boolean
	 */
	public function setConnection ($connection = '') {
		global $Config;

		$this->connection = $connection;

		if (!$connection || !$Config->db[$connection]) {
			$this->connection = key($Config->db);

			foreach ($Config->db as $connection => $settings) {
				if ($settings['default']) {
					$this->connection = $connection;
					break;
				}
			}
		}

		if ($this->connection) {
			$this->settings = $Config->db[$connection];

			if ($this->settings['type'] != 'mysql') {
				$this->Debug->fatalError(__('The database type is not "mysql"'));
			}
			return true;
		}

		return false;
	}


	/**
	 * public function getConnection ([string $connection])
	 *
	 * return boolean/string
	 */
	public function getConnection ($connection = '') {
		if ($connection) {
			return $this->connection == $connection ? true : false;
		}

		return $this->connection;
	}


	/**
	 * public function connected ()
	 *
	 * Return if connection is established
	 *
	 * return boolean
	 */
	public function connected () {
		return $this->conn ? true : false;
	}


	/**
	 * public function connect ()
	 *
	 * Start an MySQL connection
	 *
	 * return boolean
	 */
	public function connect () {
		if ($this->connected()) {
			return true;
		}

		if (!$this->settings) {
			return false;
		}

		if ($this->settings['persistent']) {
			$this->conn = @mysql_pconnect($this->settings['host'], $this->settings['user'], $this->settings['password']);
		} else {
			$this->conn = @mysql_connect($this->settings['host'], $this->settings['user'], $this->settings['password']);
		}

		if (!$this->conn) {
			$this->Debug->error('db', mysql_error());

			$this->Debug->fatalError(__('phpCan can\'t use %s connection. Please check the database configuration parameters and server network connectivity in the config file.', $this->connection));
		}

		$this->selectDB($this->settings['database']);

		mysql_query("SET NAMES 'utf8';", $this->conn);

		return true;
	}


	/**
	 * private function selectDB (string $database)
	 *
	 * Select the specified database
	 *
	 * return boolean
	 */
	private function selectDB ($database) {
		if (!@mysql_select_db($database, $this->conn)) {
			if ($test_mode) {
				return false;
			}

			$this->Debug->error('db', mysql_error());

			$this->Debug->fatalError(__('phpCan can\'t select "%s" database. Please check the database configuration parameters and server network connectivity in the config file.', $database));
		}

		return true;
	}


	/**
	 * function queryRegister ([int $offset], [int $length])
	 *
	 * Return executed queries
	 *
	 * return array
	 */
	public function queryRegister ($offset = 0, $length = null) {
		if ($offset || $length) {
			return array_slice($this->query_register, $offset, $length, true);
		}

		return $this->query_register;
	}


	/**
	 * public function result ()
	 *
	 * Get data from last query
	 *
	 * return array
	 */
	public function result () {
		if (!is_resource($this->res) || mysql_num_rows($this->res) == 0) {
			return array();
		}

		$result = array();

		while ($line = mysql_fetch_assoc($this->res)) {
			$result[] = $line;
		}

		mysql_free_result($this->res);

		return $result;
	}


	/**
	 * function query (string $query, [string $comment])
	 *
	 * Launch mysql_query function
	 *
	 * return integer
	 */
	public function query ($query, $comment = '') {
		if (!$this->connect()) {
			return false;
		}

		if (!$this->settings['simulate_saves']) {
			if (!$this->res = mysql_query($query, $this->conn)) {
				$this->Debug->error('db', mysql_error()."\n".$query);
			}
		}

		if ($this->settings['save_query_register']) {
			$backtrace = debug_backtrace();
			$location = array();

			foreach ($backtrace as $k => $v) {
				$location[$k] = $v['file'].' ('.$v['line'].')';
			}

			if ($this->settings['simulate_saves']) {
				$status = 'simulate';
			} else {
				$status = $this->res ? 'ok' : 'ko';
			}

			$this->query_register[] = array(
				'status' => $status,
				'comment' => $comment,
				'query' => $query,
				'location' => $location
			);
		}

		if ($this->settings['simulate_saves']) {
			return 0;
		}

		return !$this->res ? false : $this->affectedRows();
	}


	/**
	 * public function queryResult (string $query, [string $comment])
	 *
	 * Execute a query and return the result or false
	 *
	 * return array/false
	 */
	public function queryResult ($query, $comment = '') {
		if ($this->query($query, $comment) === false) {
			return false;
		}

		return $this->result();
	}


	/**
	 * public function getSchemaDifferences ($tables)
	 *
	 * Check differences between config tables definitions
	 * and the actual database schema
	 *
	 * return array
	 */
	public function getSchemaDifferences ($tables) {
		$this->connect();

		//Get real table definitions
		$real_tables = array();
		$real_indexes = array();

		$tmp_tables = $this->queryResult('SHOW TABLES;');

		foreach ($tmp_tables as $table) {
			$table = current($table);

			//Get indexes
			$indexes = $this->queryResult('SHOW INDEX FROM `'.$table.'`;');

			foreach ($indexes as $index) {
				if ($index['Non_unique']) {
					$type = 'index';
				} else if ($index['Key_name'] == 'PRIMARY') {
					$type = 'key';
				} else {
					$type = 'unique';
				}

				$real_indexes[$table][$index['Column_name']][$type] = $index['Key_name'];
			}

			//Get fields
			$describe = $this->queryResult('DESCRIBE `'.$table.'`;');

			foreach ($describe as $fields) {
				$type = $fields['Type'];
				$field = $fields['Field'];

				preg_match('#^(\w+)(\((.+)\))?( unsigned)?$#', $type, $t);

				if (!strstr($t[3], "'")) { //For enum values
					if (strstr($t[3], ',')) {
						list($integers, $decimals) = explode(',', $t[3]);

						$t[3] = intval($integers).','.intval($decimals);
					} else {
						$t[3] = intval($t[3]);
					}
				}

				$real_tables[$table][$field] = array(
					'type' => $t[1] == 'int' ? 'integer' : $t[1],
					'length_max' => $t[3],
					'unsigned' => $t[4] ? true : false,
					'null' => $fields['Null'] == 'NO' ? false : true,
					'incremental' => strstr($fields['Extra'], 'auto_increment') ? true : false,
					'default' => $fields['Default'],
				);

				unset($t);
			}
		}

		//Get virtual table definitions
		$virtual_tables = array();
		$virtual_indexes = array();
		$renamed_fields = array();

		foreach ($tables as $table => $table_object) {
			foreach ($table_object->formats as $format) {
				foreach ($format->getFields() as $field => $info) {
					$settings = $format->settings[$info['subformat']];

					//Get indexes
					$virtual_indexes[$table][$field] = array(
						'type' => $settings['db_type'],
						'key' => $settings['db_key'] ? 'PRIMARY' : '',
						'index' => $settings['db_index'],
						'unique' => $settings['db_unique'],
						'length' => $settings['db_length_max']
					);

					if ($settings['db_type'] == 'enum') {
						if (!is_array($settings['db_values'])) {
							$settings['db_values'] = explode(',', $settings['db_values']);
						}

						$settings['db_length_max'] = "'".implode("','", $settings['db_values'])."'";
					} else {
						if (strstr($settings['db_length_max'], ',')) {
							list($integers, $decimals) = explode(',', $settings['db_length_max']);

							$settings['db_length_max'] = intval($integers).','.intval($decimals);
						} else {
							$settings['db_length_max'] = intval($settings['db_length_max']);
						}
					}

					//Get fields
					$virtual_tables[$table][$field] = array(
						'type' => $settings['db_type'],
						'length_max' => $settings['db_length_max'],
						'unsigned' => $settings['db_unsigned'],
						'null' => $settings['db_null'],
						'incremental' => $settings['db_incremental'],
						'default' => $settings['db_default'],
					);
				}
			}
		}

		$query = array();

		$all_tables = array_merge(array_keys($real_tables), array_keys($virtual_tables));
		$all_tables = array_unique($all_tables);

		//Compare real_tables and virtual_tables fields and create the query
		foreach ($all_tables as $table) {

			//Add table
			if (!$real_tables[$table]) {
				$query_fields = array();

				//Insert fields and keys
				foreach ($virtual_tables[$table] as $field => $settings) {
					$query_fields[] =	'`'.$field.'` '.$this->fieldSchema($settings);
				}

				$query[] = 'CREATE TABLE `'.$table.'` ('.implode(', ', $query_fields).') ENGINE=MyISAM DEFAULT CHARSET=utf8;';

				continue;
			}

			//Drop table
			if (!$virtual_tables[$table]) {
				$query[] = 'DROP TABLE `'.$table.'`;';

				continue;
			}

			$all_fields = array_merge(array_keys($virtual_tables[$table]), array_keys($real_tables[$table]));
			$all_fields = array_unique($all_fields);

			foreach ($all_fields as $field) {
				//Add field
				if (!$real_tables[$table][$field]) {
					$query[] = 'ALTER TABLE `'.$table.'` ADD `'.$field.'` '.$this->fieldSchema($virtual_tables[$table][$field]).';';

					continue;
				}

				//Drop field
				if (!$virtual_tables[$table][$field]) {
					$query[] = 'ALTER TABLE `'.$table.'` DROP `'.$field.'`;';

					continue;
				}

				//Modify field
				$diff = array_diff_assoc($virtual_tables[$table][$field], $real_tables[$table][$field]);

				if ($diff) {
					$query[] = 'ALTER TABLE `'.$table.'` MODIFY `'.$field.'` '.$this->fieldSchema($virtual_tables[$table][$field]).';';
				}
			}
		}

		//Compare real_tables and virtual_tables indexes and create the query
		foreach ($virtual_indexes as $table => $fields) {
			$table_keys = array();

			foreach ($fields as $field => $key) {
				if (($key['key'] != $real_indexes[$table][$field]['key']) && ($field != 'id')) {
					$table_keys['PRIMARY']['action'] = $key['key'] ? 'ADD PRIMARY KEY' : 'DROP PRIMARY KEY';
					$table_keys['PRIMARY']['name'] = '';
					$table_keys['PRIMARY']['field'][] = array(
						'name' => $field,
						'type' => $key['type'],
						'length' => $key['length']
					);
				}

				if ($key['unique'] != $real_indexes[$table][$field]['unique']) {
					if ($real_indexes[$table][$field]['unique']) {
						$table_keys['drop-'.$real_indexes[$table][$field]['unique']] = array(
							'action' => 'DROP INDEX',
							'name' => $real_indexes[$table][$field]['unique']
						);
					}

					if ($key['unique']) {
						if (!$table_keys['add-'.$key['unique']]) {
							$table_keys['add-'.$key['unique']] = array(
								'action' => 'ADD UNIQUE',
								'name' => $key['unique'],
								'field' => array()
							);
						}

						$table_keys['add-'.$key['unique']]['field'][] = array(
							'name' => $field,
							'type' => $key['type'],
							'length' => $key['length']
						);
					}
				}

				if ($key['index'] != $real_indexes[$table][$field]['index']) {
					if ($real_indexes[$table][$field]['index']) {
						$table_keys['drop-'.$real_indexes[$table][$field]['index']] = array(
							'action' => 'DROP INDEX',
							'name' => $real_indexes[$table][$field]['index']
						);
					}

					if ($key['index']) {
						if (!$table_keys['add-'.$key['index']]) {
							$table_keys['add-'.$key['index']] = array(
								'action' => 'ADD UNIQUE',
								'name' => $key['index'],
								'field' => array()
							);
						}

						$table_keys['add-'.$key['index']]['field'][] = array(
							'name' => $field,
							'type' => $key['type'],
							'length' => $key['length']
						);
					}
				}
			}

			foreach ($table_keys as $indexes) {
				if (!$indexes['field']) {
					$query[] = 'ALTER TABLE `'.$table.'` '.$indexes['action'].' `'.$indexes['name'].'`;';
					continue;
				}

				// The length maximum for the index in UTF-8 char values is 333 bytes
				$length = intval(333 / count($indexes['field']));

				foreach ($indexes['field'] as $key => $field) {
					if (in_array($field['type'], array('varchar','text'))) {
						$indexes['field'][$key] = '`'.$field['name'].'` ('.(($length > $field['length']) ? $field['length'] : $length).')';
					} else {
						$indexes['field'][$key] = '`'.$field['name'].'`';
					}
				}

				$query[] = 'ALTER TABLE `'.$table.'` '.$indexes['action'].' `'.$indexes['name'].'` ('.implode(',', $indexes['field']).');';
			}
		}

		return $query;
	}


	/**
	 * function fieldSchema (array $field)
	 *
	 * Create each definition field line
	 *
	 * return string
	 */
	private function fieldSchema ($field) {
		$query = $field['type'];

		if ($field['length_max']) {
			$query .= '('.$field['length_max'].')';
		}

		if ($field['unsigned']) {
			$query .= ' unsigned';
		}

		$query .= $field['null'] ? ' NULL' : ' NOT NULL';

		if ($field['incremental']) {
			$query .= ' AUTO_INCREMENT PRIMARY KEY';
		} else if (isset($field['default'])) {
			$query .= ' default "'.$field['default'].'"';
		}

		return $query;
	}


	/**
	 * private function setFields (array $fields, string $table)
	 *
	 * Create the array with select fields
	 *
	 * return array
	 */
	private function setFields ($fields, $table) {
		$q_fields = array();

		foreach ($fields as $field) {
			$name = $this->getName($field);

			if ($name['new'] != $name['real']) {
				$q_fields[] = '`'.$table.'`.`'.$name['real'].'` AS `'.$name['new'].'`';
			} else {
				$q_fields[] = '`'.$table.'`.`'.$name['real'].'`';
			}
		}

		return $q_fields;
	}


	/**
	 * private function setLimit (int $offset, int $limit)
	 *
	 * Creates the limit of a query
	 *
	 * return string
	 */
	private function setLimit ($offset, $limit) {
		if ($limit) {
			if ($offset) {
				return ' LIMIT '.intval($offset).', '.intval($limit);
			} else {
				return ' LIMIT '.intval($limit);
			}
		}

		return '';
	}


	/**
	 * private function setSort (array/string $sort)
	 *
	 * Creates the sort of a query
	 *
	 * return string
	 */
	private function setSort ($sort) {
		if ($sort) {
			$sort = (array)$sort;

			foreach ($sort as &$sort_value) {
				$sort_value = preg_replace('/^([^\.]+)\.([^\s]+)/', '`$1`.`$2`', $sort_value);
			}

			return ' ORDER BY '.implode(', ', $sort);
		}

		return '';
	}


	/**
	 * private function setGroup (array/string $group)
	 *
	 * Creates the group of a query
	 *
	 * return string
	 */
	private function setGroup ($group) {
		if ($group) {
			return ' GROUP BY '.implode(', ', (array)$group);
		}

		return '';
	}


	/**
	 * function select (array $select)
	 *
	 * Sends a SELECT db query
	 *
	 * return integer
	 */
	public function select ($select) {
		if (!is_array($select)) {
			return array();
		}

		$this->connect();

		$q_fields = $q_tables = $q_where = $q_join = array();

		foreach ($select['fields'] as $table => $fields) {
			$table_name = $this->getName($table);

			$q_fields = array_merge((array)$this->setFields($fields, $table_name['new']), $q_fields);

			$q_tables[] = $this->setTable($table_name);
		}

		foreach ((array)$select['fields_commands'] as $command) {
			$q_fields[] = $command;
		}

		if (is_array($select['join'])) {
			$q_join_tables_all = array();

			foreach ($select['join'] as $join) {
				$q_join_tables = array();

				foreach ($join['fields'] as $table => $fields) {
					$table_name = $this->getName($table);

					$q_fields = array_merge((array)$this->setFields($fields, $table_name['new']), $q_fields);

					$table = $table;

					if (!in_array($table, $q_tables) && !in_array($table, $q_join_tables_all)) {
						$q_join_tables[] = $q_join_tables_all[] = $table;
					}
				}

				$q_join[] = array(
					'tables' => $q_join_tables,
					'conditions' => $join['conditions']
				);
			}
		}

		if (!count($q_fields)) {
			return false;
		}

		$q_tables = array_unique($q_tables);

		$query = 'SELECT '.implode(', ', $q_fields).' FROM ('.implode(', ', $q_tables).')';

		if (count($q_join)) {
			foreach ($q_join as $join) {
				$query .= ' LEFT JOIN ('.implode(', ', $join['tables']).') ON ('.$this->where($join['conditions']).')';
			}
		}

		if (count($select['conditions'])) {
			$conditions = $this->where($select['conditions'], 'AND');

			if ($conditions) {
				$query .= ' WHERE '.$conditions;
			}
		}

		$query .= $this->setGroup($select['group']);
		$query .= $this->setSort($select['sort']);
		$query .= $this->setLimit($select['offset'], $select['limit']);

		return $this->queryResult($query.';', $select['comment']);
	}


	/**
	 * public function insert (array $data)
	 *
	 * Execute the insert action
	 *
	 * return false/integer
	 */
	public function insert ($data) {
		if (!$data['table'] || !$data['data'] || !is_array($data['data'])) {
			return false;
		}

		$this->connect();

		$table = $data['table'];

		if (!is_int(key($data['data']))) {
			$data['data'] = array($data['data']);
		}

		unset($data['data']['id']);

		$fields = array();

		foreach ($data['data'] as $row) {
			if (!is_array($row)) {
				continue;
			}

			$fieldsRow = array_keys($row);
			$fields = array_merge($fields, $fieldsRow);
		}

		$fields = array_unique($fields);
		$query_fields = '(`'.implode('`, `', $fields).'`)';

		$values = array();

		foreach ($data['data'] as $row) {
			$valueRow = array();

			foreach ($fields as $field) {
				$valueRow[] = $this->escapeString($row[$field]);
			}

			$valueRow = '("'.implode('", "', $valueRow).'")';
			$values[] = $valueRow;
		}

		$values = implode(', ', $values);

		$query = 'INSERT INTO `'.$table.'` '.$query_fields.' VALUES '.$values.';';

		if ($this->query($query, $data['comment']) === false) {
			return false;
		}

		return $this->affectedRows();
	}


	/**
	 * public function replace (array $data)
	 *
	 * Execute the replace action
	 *
	 * return integer
	 */
	public function replace ($data) {
		if (!$data['table'] || !$data['data'] || !is_array($data['data'])) {
			return false;
		}

		$this->connect();

		$table = $data['table'];

		if (!is_int(key($data['data']))) {
			$data['data'] = array($data['data']);
		}

		$fields = array();

		foreach ($data['data'] as $row) {
			$fieldsRow = array_keys($row);
			$fields = array_merge($fields, $fieldsRow);
		}

		$fields = array_unique($fields);
		$query_fields = '(`'.implode('`, `', $fields).'`)';

		$values = array();

		foreach ($data['data'] as $row) {
			$valueRow = array();

			foreach ($fields as $field) {
				$valueRow[] = $this->escapeString($row[$field]);
			}

			$valueRow = '("'.implode('", "', $valueRow).'")';
			$values[] = $valueRow;
		}
		$values = implode(', ', $values);

		$query = 'REPLACE INTO `'.$table.'` '.$query_fields.' VALUES '.$values.';';

		if ($this->query($query, $data['comment']) === false) {
			return false;
		}

		return $this->affectedRows();
	}


	/**
	 * public function lastId (void)
	 *
	 * Return the last insert id
	 *
	 * return integer
	 */
	public function lastId () {
		return mysql_insert_id();
	}


	/**
	 * public function affectedRows (void)
	 *
	 * Return the number of affected rows in the last mysql query
	 *
	 * return integer
	 */
	public function affectedRows () {
		return mysql_affected_rows();
	}


	/**
	 * public function update (array $data)
	 *
	 * Execute the update action
	 *
	 * return integer
	 */
	public function update ($data) {
		if (!$data['table'] || !$data['data'] || !is_array($data['data'])) {
			return false;
		}

		$this->connect();

		$table = $data['table'];

		$query = 'UPDATE `'.$table.'` SET ';

		foreach ($data['data'] as $field => $value) {
			if (is_integer($field)) {
				$query .= $value.', ';
			} else {
				$query .= '`'.$field.'` = "'.$this->escapeString($value).'", ';
			}
		}

		$query = substr($query, 0, -2);

		if ($data['conditions'] && (is_array($data['conditions']) || $data['conditions'] == 'all')) {
			$data['conditions'] = $this->where($data['conditions']);

			if ($data['conditions']) {
				$query .= ' WHERE '.$data['conditions'];
			}

			$query .= $this->setSort($data['sort']);
			$query .= $this->setLimit($data['offset'], $data['limit']);
			$query .= ';';
		} else {
			$this->Debug->error('db', __('For security, conditions param is needed to delete function. If you want delete all rows, use conditions = "all"'));

			return false;
		}

		if ($this->query($query, $data['comment']) === false) {
			return false;
		}

		return $this->affectedRows();
	}


	/**
	 * public function delete (string $data)
	 *
	 * Delete data stored in a database table
	 *
	 * return boolean
	 */
	public function delete ($data) {
		if (!$data['table']) {
			return false;
		}

		$this->connect();

		$table = $data['table'];

		$query = 'DELETE FROM `'.$table.'`';

		if ($data['conditions'] && (is_array($data['conditions']) || $data['conditions'] == 'all')) {
			$data['conditions'] = $this->where($data['conditions']);

			if (!$data['conditions'] && !$data['limit']) {
				$query = 'TRUNCATE `'.$table.'`;';
			} else if ($data['conditions']) {
				$query .= ' WHERE '.$data['conditions'];
			}

			$query .= $this->setSort($data['sort']);
			$query .= $this->setLimit($data['offset'], $data['limit']);
			$query .= ';';
		} else {
			$this->Debug->error('db', __('For security, conditions param is needed to delete function. If you want delete all rows, use conditions = "all"'));

			return false;
		}

		if ($this->query($query, $data['comment']) === false) {
			return false;
		}

		return $this->affectedRows();
	}


	/**
	 * private function where (array $conditions)
	 *
	 * Create a WHERE string
	 *
	 * return string
	 */
	private function where ($conditions, $first = 'AND') {
		if ($conditions == 'all') {
			return '';
		}

		$q = '';

		if ($first == 'AND') {
			$second = 'OR';
		} else {
			$first = 'OR';
			$second = 'AND';
		}

		foreach ($conditions as $key => $value) {
			if (is_int($key)) {
				if (is_array($value)) {
					$q .= ' ('.trim($this->where($value, $second)).') '.$first;
					continue;
				} else {
					$q .= ' '.$value;
				}
			} else {
				preg_match('/^([0-9]+ )?([^\s]+)\s?(.*)$/', $key, $options);

				$field = trim($options[2]);
				$mode = trim($options[3]);

				if (empty($field)) {
					continue;
				}

				if (strpos($field, '.')) {
					$field = '`'.str_replace('.', '`.`', $field).'`';
				} else {
					$field = '`'.$field.'`';
				}

				$value = $this->escapeString($value);

				switch ($mode) {
					case '':
					case '=':
					case 'IN':
						if (is_array($value)) {
							if (count($value) > 1) {
								$q .= ' '.$field.' IN ("'.implode('","', array_unique((array)$value)).'")';
							} else {
								$q .= ' '.$field.' = "'.current($value).'"';
							}
						} else {
							$q .= ' '.$field.' = "'.$value.'"';
						}
						break;
					case '!=':
					case 'NOT':
						if (is_array($value)) {
							if (count($value) > 1) {
								$q .= ' '.$field.' NOT IN ("'.implode('","', array_unique((array)$value)).'")';
							} else {
								$q .= ' '.$field.' != "'.current($value).'"';
							}
						} else {
							$q .= ' '.$field.' != "'.$value.'"';
						}
						break;
					case 'BETWEEN':
						$q .= ' '.$field.' BETWEEN "'.$value[0].'" AND "'.$value[1].'"';
						break;
					case '>':
					case '>=':
					case '<':
					case '<=':
					case 'LIKE':
					case 'NOT LIKE':
					case 'REGEXP':
						$q .= ' '.$field.' '.$mode.' "'.$value.'"';
						break;
					case 'IS NULL':
						$q .= ' '.$field.' IS NULL';
						break;
				}
			}

			$q .= ' '.$first;
		}

		$q = trim($q);

		return substr($q, 0, strrpos($q, ' '));
	}


	/**
	 * public function escapeString (mixed $values)
	 *
	 * Apply the mysql_real_escape_string to values
	 *
	 * return mixed
	 */
	public function escapeString ($values) {
		if (is_array($values)) {
			foreach ($values as $key => $value) {
				if (is_string($value)) {
					$values[$key] = mysql_real_escape_string(str_replace(array("\r\n", "\r"), "\n", trim($value)), $this->conn);
				} else {
					$values[$key] = $this->escapeString($value);
				}
			}

			return $values;
		} else {
			return mysql_real_escape_string(str_replace(array("\r\n", "\r"), "\n", trim($values)), $this->conn);
		}
	}


	/**
	 * private function setTable (array $table)
	 *
	 * return false/string
	 */
	private function setTable ($table) {
		if (!$table['real']) {
			return false;
		}

		return ($table['real'] == $table['new']) ? ('`'.$table['real'].'`') : ('`'.$table['real'].'` AS `'.$table['new'].'`');
	}


	/**
	 * private function getName (string $table)
	 *
	 * return false/array
	 */
	private function getName ($table) {
		if (!$table) {
			return false;
		}

		if (strstr($table, '[')) {
			preg_match_all('/[\w-]+/', $table, $tables);

			return array(
				'real' => trim($tables[0][0]),
				'new' => trim($tables[0][1])
			);
		}

		return array(
			'real' => $table,
			'new' => $table,
		);
	}
}
?>
